home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 428_02 / libsrc / msgbox.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-13  |  4.3 KB  |  171 lines

  1. /*
  2. ** msgbox.c
  3. **
  4. ** Pictor, Version 1.51, Copyright (c) 1992-94 SoftCircuits
  5. ** Redistributed by permission.
  6. */
  7.  
  8. #include <stdio.h>
  9. #include <ctype.h>
  10. #include "pictor.h"
  11.  
  12.  
  13. static struct {
  14.     int numitems;
  15.     char *items[3];
  16. } buttons[] = {
  17.     { 1,{"    ~OK    ", NULL,NULL}, },
  18.     { 2,{"    ~OK    ", "   ~Cancel   ",NULL}, },
  19.     { 2,{"   ~Retry   ","   ~Cancel   ",NULL}, },
  20.     { 2,{"   ~Retry   ","   ~Abort   ", NULL}, },
  21.     { 2,{"   ~Yes   ",  "    ~No    ",NULL}, },
  22.     { 3,{"   ~Yes   ",  "    ~No    ","   ~Cancel   "}, },
  23. };
  24.  
  25. #define MAX_LINES 15
  26. static int linelen[MAX_LINES];      /* length of each line */
  27.  
  28. /*
  29. ** Displays a message box. If the user presses Enter, it returns a
  30. ** value indicating which selection was made. 0 indicates the right-most
  31. ** selection, 1 indicates the second-to-right selection, and so on. If
  32. ** flags == MB_OK the return value is always 0.
  33. **
  34. ** 0 is returned if Escape is pressed. Use the escpressed() macro to
  35. ** determine if 0 was returned because Escape was pressed or the
  36. ** right-most item was selected.
  37. **
  38. ** NOTE: This function can be called recursively if it is active and:
  39. ** 1) a critical error occurs, 2) help is selected.
  40. **
  41. ** WARNING: This function gets called from the critical-error
  42. ** interrupt handler. The handler safely disables help and
  43. ** this function calls wopen with the WO_STATICMEM attribute.
  44. ** If you modify this function, don't call any routine that,
  45. ** in-turn, calls malloc.
  46. */
  47. int messagebox(char *msg,char *title,int flags,COLORSTRUCT *colors)
  48. {
  49.     int i,j,key,buttonwidth,top,left,width,height;
  50.     int selection = 0,done = FALSE,update = TRUE;
  51.     int maxlen = 0,currlen = 0;
  52.     int numlines = 0;
  53.  
  54.     /* determine number of lines and */
  55.     /* length of the longest line */
  56.     for(i = 0;msg[i] != '\0';i++) {
  57.         if(msg[i] == '\n') {
  58.             /* test for too many lines */
  59.             if((numlines + 1) >= MAX_LINES)
  60.                 break;
  61.  
  62.             linelen[numlines] = currlen;
  63.             numlines++;
  64.             currlen = 0;
  65.         }
  66.         else currlen++;
  67.  
  68.         if(currlen > maxlen)
  69.             maxlen = currlen;
  70.     }
  71.     /* count last line */
  72.     linelen[numlines] = currlen;
  73.     numlines++;
  74.  
  75.     /* get width of all buttons side-by-side */
  76.     for(buttonwidth = 0,i = 0;i < buttons[flags].numitems;i++)
  77.         buttonwidth += hstrlen(buttons[flags].items[i]);
  78.  
  79.     /* calculate window coordinates */
  80.     height = numlines + 4;
  81.     width = ((maxlen > buttonwidth) ? maxlen : buttonwidth) + 4;
  82.     top = center(height + 2,_PL_rows);
  83.     left = center(width + 2,_PL_columns);
  84.  
  85.     wopen(top,left,height + 2,width + 2,colors->normal,
  86.         WO_STATICMEM | WO_SHADOW);
  87.     wtitle(title);
  88.  
  89.     /* display message text */
  90.     for(i = 0,j = 0;i < numlines;i++,j++) {
  91.         setwpos(i + 2,center(linelen[i],width));
  92.         while(msg[j] != '\0' && msg[j] != '\n')
  93.             wputc(msg[j++]);
  94.     }
  95.  
  96.     while(!done) {
  97.         if(update) {
  98.             setvpos((top + height) - 1,left + center(buttonwidth,width));
  99.             for(i = 0;i < buttons[flags].numitems;i++) {
  100.                 if(i == selection) {
  101.                     vcolor(colors->select);
  102.                     hputs(buttons[flags].items[i],colors->boldselect);
  103.                 }
  104.                 else {
  105.                     vcolor(colors->normal);
  106.                     hputs(buttons[flags].items[i],colors->boldnormal);
  107.                 }
  108.             }
  109.             update = FALSE;
  110.         }
  111.  
  112.         switch(key = kbdread()) {
  113.             case LEFT_KEY:
  114.                 if(buttons[flags].numitems == 1) {
  115.                     beep();
  116.                 }
  117.                 else {
  118.                     if(selection > 0)
  119.                         selection--;
  120.                     else
  121.                         selection = (buttons[flags].numitems - 1);
  122.                     update = TRUE;
  123.                 }
  124.                 break;
  125.             case RIGHT_KEY:
  126.             case SPACE_BAR:
  127.                 if(buttons[flags].numitems == 1) {
  128.                     beep();
  129.                 }
  130.                 else {
  131.                     if(selection < (buttons[flags].numitems - 1))
  132.                         selection++;
  133.                     else
  134.                         selection = 0;
  135.                     update = TRUE;
  136.                 }
  137.                 break;
  138.             case ENTER_KEY:
  139.                 done = TRUE;
  140.                 break;
  141.             case ESCAPE_KEY:
  142.                 selection = (buttons[flags].numitems - 1);
  143.                 done = TRUE;
  144.                 break;
  145.             case F1_KEY:
  146.                 if(_PL_helpfunc != NULL)
  147.                     _PL_helpfunc(_PL_helpcontext);
  148.                 else beep();
  149.                 break;
  150.             default:     /* check for hot-key */
  151.                 key &= 0xFF;
  152.                 if(isalnum(key)) {
  153.                     key = tolower(key);
  154.                     for(i = 0;i < buttons[flags].numitems;i++) {
  155.                         if(key == tolower(gethotkey(buttons[flags].items[i]))) {
  156.                             selection = i;
  157.                             done = TRUE;
  158.                             break;
  159.                         }
  160.                     }
  161.                 }
  162.                 if(!done) beep();
  163.                 break;
  164.         }
  165.     }
  166.     wclose();
  167.  
  168.     return((buttons[flags].numitems - 1) -    selection);
  169.  
  170. } /* messagebox */
  171.